package org.rainbowinverted.charging.device.connect.ykc.server.handler;

import cn.hutool.core.util.HexUtil;
import org.rainbowinverted.charging.device.connect.ykc.server.constants.YkcTimeRangeFeeRateEnum;
import org.rainbowinverted.charging.device.connect.ykc.server.message.in.YkcChargeStandardIn;
import org.rainbowinverted.charging.device.connect.ykc.server.message.in.YkcMessageIn;
import org.rainbowinverted.charging.device.connect.ykc.server.message.out.YkcChargeStandardOut;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 计费标准同步处理器
 *
 * @author hehuaiping
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class YkcChargeStandardSyncHandler extends YkcAbstractHandler<YkcChargeStandardIn, YkcChargeStandardOut> {
    @Override
    public void read(ChannelHandlerContext channel, YkcMessageIn message) {
        Long deviceNo = readDeviceNo(message.getMessageBody());
        log.info("charge standard sync deviceNo:{}", deviceNo);
        channel.writeAndFlush(syncChargeStandardModel(message.getFrameSerialNo(), deviceNo));
    }

    @Override
    public void write(ByteBuf byteBuf, YkcChargeStandardOut ykcChargeStandardOut) {
        writeDeviceNo(byteBuf, ykcChargeStandardOut.getDeviceNo());
        // 固定值：0100
        byteBuf.writeBytes(HexUtil.decodeHex(String.format("%04d", ykcChargeStandardOut.getChargeStandardModelNo())));
        // 尖、峰、平、谷费用精确到五位小数
        byteBuf.writeIntLE(ykcChargeStandardOut.getSharpElectricityFee());
        byteBuf.writeIntLE(ykcChargeStandardOut.getSharpServiceFee());
        byteBuf.writeIntLE(ykcChargeStandardOut.getPeakElectricityFee());
        byteBuf.writeIntLE(ykcChargeStandardOut.getPeakServiceFee());
        byteBuf.writeIntLE(ykcChargeStandardOut.getFlatServiceFee());
        byteBuf.writeIntLE(ykcChargeStandardOut.getFlatServiceFee());
        byteBuf.writeIntLE(ykcChargeStandardOut.getValleyServiceFee());
        byteBuf.writeIntLE(ykcChargeStandardOut.getValleyServiceFee());
        for (int i = 0; i < ykcChargeStandardOut.getTimeRangeFeeRate().length; i++) {
            byteBuf.writeByte(ykcChargeStandardOut.getTimeRangeFeeRate()[i].getFeeRate());
        }
    }

    /**
     * 同步计费模型
     *
     * @param frameSerialNo 帧序列号
     * @param deviceNo      设备编号
     */
    private YkcChargeStandardOut syncChargeStandardModel(Integer frameSerialNo, Long deviceNo) {
        YkcTimeRangeFeeRateEnum[] rangeFeeRateEnums = new YkcTimeRangeFeeRateEnum[48];
        for (int i = 0; i < rangeFeeRateEnums.length; i++) {
            if (i <= 14) {
                rangeFeeRateEnums[i] = YkcTimeRangeFeeRateEnum.VALLEY;
            } else if (i <= 22) {
                rangeFeeRateEnums[i] = YkcTimeRangeFeeRateEnum.FLAT;
            } else if (i <= 38) {
                rangeFeeRateEnums[i] = YkcTimeRangeFeeRateEnum.SHARP;
            } else if (i <= 46) {
                rangeFeeRateEnums[i] = YkcTimeRangeFeeRateEnum.PEAK;
            } else {
                rangeFeeRateEnums[i] = YkcTimeRangeFeeRateEnum.VALLEY;
            }
        }
        return YkcChargeStandardOut.of(frameSerialNo, deviceNo,
                16000, 54000,
                16000, 54000,
                16000, 54000,
                16000, 54000, rangeFeeRateEnums);
    }
}
